//
// Created by hkkzzxz on 24-9-2.
//

#include "Security.h"
#include <vector>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <sstream>
#include <iomanip>

std::string Security::generateSalt() {
    std::vector<unsigned char> salt(SALT_LENGTH);
    RAND_bytes(salt.data(), SALT_LENGTH);
    std::string saltStr;
    static const char *hexDigits = "0123456789ABCDEF";
    for (unsigned char c: salt) {
        saltStr += hexDigits[(c & 0xF0) >> 4];
        saltStr += hexDigits[c & 0x0F];
    }
    consoleLogger->info("generate salt successful");
    return saltStr;
}

std::string Security::hashPassword(const std::string &password, const std::string &salt) {
    unsigned char *derivedKey = NULL;
    unsigned int derivedKeyLength = EVP_MAX_MD_SIZE;

    derivedKey = static_cast<unsigned char *>(OPENSSL_malloc(derivedKeyLength));
    if (!derivedKey) {
        OPENSSL_free(derivedKey);
        return "";
    }

    // 使用EVP_PBE库实现PBKDF2
    if (PKCS5_PBKDF2_HMAC(password.c_str(), password.length(),
                          reinterpret_cast<const unsigned char *>(salt.c_str()), salt.length(),
                          88, EVP_sha256(), derivedKeyLength, derivedKey) != 1) {
        OPENSSL_free(derivedKey);
        return "";
    }

    std::stringstream hashedPassword;
    hashedPassword << std::hex << std::setfill('0');
    for (size_t i = 0; i < derivedKeyLength; ++i) {
        hashedPassword << std::setw(2) << static_cast<int>(derivedKey[i]);
    }

    // 清理分配的内存
    OPENSSL_free(derivedKey);

    consoleLogger->info("hash password successful");
    return hashedPassword.str();
}
